home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 17124 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.0 KB

  1. Path: ix.netcom.com!news
  2. From: miker3@ix.netcom.com (Mike Rubenstein)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: operator<< precedence, cout, and weirdness
  5. Date: Sat, 13 Apr 1996 08:58:58 GMT
  6. Organization: Netcom
  7. Message-ID: <316f6811.209729505@nntp.ix.netcom.com>
  8. References: <1996Apr12.133813.78123@cc.usu.edu>
  9. NNTP-Posting-Host: ix-dc6-23.ix.netcom.com
  10. X-NETCOM-Date: Sat Apr 13  3:57:54 AM CDT 1996
  11. X-Newsreader: Forte Agent .99d/32.182
  12.  
  13. pjh@gas.physics.usu.edu (Paul Hepworth) wrote:
  14.  
  15. > I'm having a hard time figuring out the weird eval order
  16. > of these operator<< expressions:
  17. > Here is the output from the prog below:
  18. > 2220
  19. > 2220
  20. > It appears the i++/++i expressions are being evaluated right to
  21. > left instead of left to right.
  22. > I included a parenthesized version to explicitly specify
  23. > the order I think it should already be evaluated in, and it
  24. > gives the same result.
  25. > What's the deal?!
  26. > #include <stream.h>
  27. > int main()
  28. > {
  29. >   int i=0;
  30. >   
  31. >   cout << i++ << i << ++i << i++ << endl;
  32. >   cout << i << endl;
  33. >   i=0;
  34. >   (((( cout << i++) << i) << ++i) << i++) << endl;
  35. >   cout << i << endl;
  36. > }
  37. > I think it should evaluate as follows:
  38. > i++, producing integer result 
  39. > cout << above result, producing istream&
  40. > above result << i, producing istream&
  41. > ++i, producing integer
  42. > above istream& << above integer result, producing istream&
  43. > i++, producing integer
  44. > above istream& << above integer, producing istream&
  45. > above istream& << endl, producing istream&
  46. > instead, it seems to evaluate the i++/++i expressions to temporaries,
  47. > then cout << tmp1 << tmp2....
  48. > BTW, with numbers, it evaluates as expected:
  49. > 1 << 1 << 2 produces 8, not 16
  50.  
  51. The deal is that C++ does not specify the order in which operands are
  52. evaluated except for a few operators.  << is not one of these.  The
  53. compiler is free to order the evaluations in any way it finds
  54. convenient.
  55.  
  56. Parentheses affect the order of evaluation of operators, but not
  57. operands.  Your parentheses don't matter here since the order of
  58. evaluation of the operators is the same as you specify.  In either
  59. case, the order of evaluation of the operators will be
  60.  
  61.     cout << i++ << i << ++i << i++ << endl;
  62.           1      2    3      4      5
  63.  
  64. But the operands may be evaluated in any order.  consider
  65.  
  66.     cout << A << B;
  67.  
  68. The compiler may
  69.  
  70.     1.  evaluate A
  71.     2.  evaluate cout << A
  72.     3.  evaluate B
  73.     4.  evaluate (the result of 2) << B
  74.  
  75. That's what you expect.  But it may also
  76.  
  77.     1.  evaluate B
  78.     2.  evaluate A
  79.     3.  evaluate cout << A
  80.     4.  evaluate (the result of 3) << (the result of 1)
  81.  
  82. Actually it gets worse.  Side-effects may take place any time between
  83. sequence points.  Since << does not introduce a sequence point, even
  84. if the value of A is determined first, side-effects may not be done
  85. until after the evaluation of B.
  86.  
  87. And even worse.  The above is accurate in practice, but the language
  88. definition gives the compiler even more freedom.  Modifying a variable
  89. twice between sequence points results in undefined behavior.  Anything
  90. may happen in your example -- no result or output need even be
  91. produced.
  92.  
  93.  
  94. Michael M Rubenstein
  95.